/**
 ****************************************
 * @file shell.h
 * @author: AnRui
 * @version 0.1
 * @date  : 2025-11-09
 * @copyright Copyright (c) 2025
 * @desc: 1.串口的初始化 我放在别的地方 根据情况可以自定义
 *        上下翻历史命令 修改没成功 待完善
 * ***************************************
 */
#ifndef _SHELL_H
#define _SHELL_H
#include "gd32f30x.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
#include "total_config.h"

#define SHELL_ENTER_CRITICAL()    (taskENTER_CRITICAL())
#define SHELL_EXIT_CRITICAL()     (taskEXIT_CRITICAL())

 // #define SHELL_ENTER_CRITICAL()   
 // #define SHELL_EXIT_CRITICAL()   

  // 使能命令回显（输入字符时在终端显示）
#define SHELL_ECHO_MODE 1
// 命令最大长度（默认80字符）
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE      80
#endif
// 命令历史记录行数
#define FINSH_HISTORY_LINES 5
// 最大参数数量
#define FINSH_ARG_MAX    8

// 终端提示符（命令行前缀）
#define FINSH_PROMPT "AR'shell> "

// 遍历系统调用表的宏
#define FINSH_NEXT_SYSCALL(index)  index=finsh_syscall_next(index)

// 系统调用函数指针类型
typedef long (*syscall_func)(void);


// 输入状态枚举
enum input_stat {
    WAIT_NORMAL,       // 正常输入状态
    WAIT_SPEC_KEY,     // 等待特殊键（如ESC后的中间字符）
    WAIT_FUNC_KEY      // 等待功能键（如上下左右键）
};

// Shell核心结构体（存储输入状态、命令行数据等）
struct finsh_shell {
    enum input_stat stat;               // 当前输入状态
    uint8_t line[FINSH_CMD_SIZE + 1];   // 存储当前输入的命令行
    uint16_t line_position;             // 命令行当前长度（字符总数）
    uint16_t line_curpos;               // 当前光标位置
    uint16_t current_history;           // 当前选中的历史记录索引
    uint16_t history_count;             // 历史记录总数
    char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE]; // 历史记录存储数组
    uint8_t recv_data;                  // 接收的单个字符
};

// 系统调用表结构体（存储命令信息）
struct finsh_syscall {
    const char* name;       // 命令名称
    const char* desc;       // 命令描述
    syscall_func  func;   // 命令对应的函数指针
};

// 用于将变量/函数放入指定段的属性定义
#define __USED__	__attribute__((__used__))
#define __SECTION(x)  __attribute__((section(x)))

// 命令导出宏（用于注册自定义命令）
#define CLI_CMD_EXPORT(command, desc)   \
    FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)

// 命令注册底层宏（将命令信息存入指定段，供系统遍历）
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc)                      \
   const char __fsym_##cmd##_name[] __SECTION(".rodata.name") = #cmd;    \
   const char __fsym_##cmd##_desc[] __SECTION(".rodata.name") = #desc;   \
   __USED__ const struct finsh_syscall __fsym_##cmd __SECTION("FSymTab")= \
   {                        \
    __fsym_##cmd##_name,    \
    __fsym_##cmd##_desc,    \
    (syscall_func)&name     \
   };

// 命令函数类型定义（参数为argc（参数数量）和argv（参数数组））
typedef int (*cmd_function_t)(int argc, char** argv);

// 命令表的起始和结束地址（-----由链接器生成-------------）
extern const int FSymTab$$Base;
extern const int FSymTab$$Limit;
// 系统调用表的全局指针
extern struct finsh_syscall* _syscall_table_begin;
extern struct finsh_syscall* _syscall_table_end;

// 函数声明
void shell_init(void);                      // Shell初始化
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call); // 遍历命令表
int help(int argc, char** argv);            // 帮助命令

#endif

